package ru.sgu.codecenter.fidx.command;

import ru.sgu.codecenter.fidx.OperationFailedException;
import ru.sgu.codecenter.fidx.model.FileDocument;
import ru.sgu.codecenter.fidx.model.HelpItem;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DeleteCommand extends Command {
    @Override
    public String getName() {
        return "delete";
    }

    @Override
    public List<HelpItem> getHelpItems() {
        List<HelpItem> helpItems = new ArrayList<HelpItem>();
        helpItems.add(new HelpItem(getName() + " <file or directory>", "delete file or directory in the index with whole subtree"));
        return helpItems;
    }

    @Override
    public void execute(String[] args) {
        for (String arg : args) {
            deleteFileOrDirectory(new File(arg));
        }
    }

    private void deleteFileOrDirectory(File file) {
        if (!file.exists()) {
            warn("Can't find file \"" + file + "\".");
            return;
        }

        if (file.isFile()) {
            deleteFile(file);
            return;
        }

        if (file.isDirectory()) {
            deleteDirectory(file);
            return;
        }

        warn("The path \"" + file + "\" is nether file nor directory.");
    }

    private void deleteFile(File file) {
        String path;
        try {
            path = file.getCanonicalPath();
        } catch (IOException e) {
            throw new OperationFailedException("File [file=\"" + file + "\"] for deleting is incorrect.", e);
        }

        List<FileDocument> searchResults = engine.findByFilePath(path);
        if (searchResults.size() > 1) {
            warn("Too many files in index have exact name \"" + path + "\".");
            return;
        }

        for (FileDocument searchResult : searchResults) {
            engine.delete(searchResult);
        }

        if (searchResults.size() == 1) {
            info("File \"" + path + "\" has been deleted.");
        } else {
            info("Cannot find \"" + path + "\" in the index.");
        }
    }

    void deleteDirectory(File directory) {
        int deletedFileCount = 0;
        List<FileDocument> searchResults;
        do {
            try {
                searchResults = engine.findByFilePathPrefix(directory.getCanonicalPath());
            } catch (Exception e) {
                break;
            }

            for (FileDocument searchResult : searchResults) {
                engine.delete(searchResult);
                info("Deleted from index \"" + searchResult.getPath() + "\".");
            }
            deletedFileCount += searchResults.size();
        }
        while (searchResults.size() != 0);

        info(deletedFileCount + " entries has been deleted from index.");
    }
}
